package com.wjjun.base.ui.helper

import androidx.databinding.ViewDataBinding
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.wjjun.base.BR
import com.wjjun.base.ui.listener.IRefreshViewListener
import com.wjjun.base.ui.viewmodel.BaseItemViewModel
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch

/**
 * RecycleView 刷新、加载 助手类
 * author : wangjunjun
 * date   : 2022/6/8
 * desc   :
 */
open class RefreshRecycleViewHelper : RecycleViewHelper(), IRefreshViewListener {

    val mainScope = MainScope()

    val DEFAULT_PAGE_NUM = 1
    val DEFAULT_PAGE_SIZE = 10

    //获取数据回调
    var dataProvide: DataProvide? = null
    protected var refreshLayout: RefreshLayout? = null
    private var firstPageNum = DEFAULT_PAGE_NUM
    private var pageNum = DEFAULT_PAGE_NUM
    private var pageSize = DEFAULT_PAGE_SIZE

    //标记数据是否变化
    private var dataChange = false

    /**
     * 绑定viewModel和事件
     */
    open fun bindViewDataBinding(viewDataBinding: ViewDataBinding) {
        //数据、事件绑定
        viewDataBinding.setVariable(BR.listViewModel, collectionViewModel)
        viewDataBinding.setVariable(BR.listListener, this)
    }

    override fun initRefresh(refreshLayout: RefreshLayout) {
        this.refreshLayout = refreshLayout
        refreshLayout.setOnRefreshListener {
            refreshData()
        }
        refreshLayout.setOnLoadMoreListener {
            loadData()
        }
    }

    override fun onRefresh(refreshLayout: RefreshLayout?) {
        refreshData()
    }

    override fun onLoadMore(refreshLayout: RefreshLayout?) {
        this.pageNum++
        fetchData(pageNum, pageSize, false)
    }

    /**
     * 带刷新动画的刷新
     */
    fun refreshDataShowAnim() {
        refreshLayout?.autoLoadMoreAnimationOnly()
        refreshData()
    }

    /**
     * 刷新数据
     */
    fun refreshData(useCache: Boolean = false) {
        pageNum = DEFAULT_PAGE_NUM
        fetchData(pageNum, pageSize, useCache)
    }

    /**
     * 延迟刷新
     */
    open fun lazyRefreshData() {
        refreshLayout?.autoRefresh(500) ?: refreshData()
    }

    /**
     * 加载更多数据
     */
    private fun loadData() {
        pageNum++
        fetchData(pageNum, pageSize, false)
    }

    /**
     * 从网络获取数据
     */
    protected open fun fetchData(pageNum: Int, pageSize: Int, useCache: Boolean) {
        mainScope.launch {
            dataProvide?.fetchData(pageNum, pageSize, useCache, null)
        }
    }

    /**
     * 通知数据变化
     */
    fun notifyDataChange() {
        //如果可见,则直接刷新
        if (isShow) {
            lazyRefreshData()
        } else {
            dataChange = true
        }
    }

    override fun onShow() {
        super.onShow()
        if (dataChange) {
            dataChange = false
            refreshData()
        }
    }

    override fun onLifeDestroy() {
        super.onLifeDestroy()
        dataProvide = null
        mainScope.cancel()
    }


    /**
     * 添加数据，页码如为0，则会清空原有数据
     */
    open fun setData(itemViewModels: List<BaseItemViewModel<*>>?, pageNum: Int = DEFAULT_PAGE_NUM) {
        if (pageNum <= firstPageNum) {
            collectionViewModel.clear()
        }

        if (itemViewModels == null || itemViewModels.isEmpty()) {
            finishLoadMore(true)
        } else {
            this.pageNum = pageNum
            collectionViewModel.addAll(itemViewModels)
            if (itemViewModels.size < pageSize) {
                finishLoadMore(true)
            } else {
                finishLoadMore(false)
            }
        }
        finisRefresh()
    }

    open fun finisRefresh() {
        refreshLayout?.finishLoadMore(10)
        refreshLayout?.finishRefresh(10)
    }

    open fun finishLoadMore(noMoreData: Boolean) {
        collectionViewModel.state.noMoreData.set(noMoreData)
        collectionViewModel.state.noMoreData.notifyChange()
    }

    /**
     * 设置是否可以刷新
     */
    fun setRefreshEnable(enable: Boolean) {
        collectionViewModel.state.enableRefresh.set(enable)
    }

    /**
     * 设置是否自动加载更多
     */
    fun setLoadMoreEnable(enable: Boolean) {
        collectionViewModel.state.enableLoadMore.set(enable)
    }

    /**
     * 设置是否拖动
     */
    fun setDragEnable(enable: Boolean){
        collectionViewModel.state.drag.set(enable)
    }


    interface DataProvide {
        /**
         * 获取数据,获取完后请回调
         */
        suspend fun fetchData(pageNum: Int, pageSize: Int, useCache: Boolean, param: Any?)
    }

}